﻿using Anno;
using Microsoft.AspNetCore.Http;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;

namespace Microsoft.AspNetCore
{
    public class ApiRequest
    {
        private string _pathPattern;
        public ApiRequest(HttpRequest request, string pathPattern)
        {
            HttpRequest = request;
            _pathPattern = pathPattern;
        }

        public HttpRequest HttpRequest { get; }

        private IDictionary<string, string> _params;
        public IDictionary<string, string> Params => _params ?? (_params = PathUtil.MatchPathParams(HttpRequest.Path, _pathPattern));

        private IDictionary<string, string> _query;
        public IDictionary<string, string> Query => _query ?? (_query = DynamicQuery());

        private IDictionary<string, string> _header;
        public IDictionary<string, string> Headers => _header ?? (_header = DynamicHeader());
        private IDictionary<string, string> _cookie;
        public IDictionary<string, string> Cookies => _cookie ?? (_cookie = DynamicCookies());

        public Stream BodyStream => HttpRequest.Body;

        private string _bodyContent;
        public string BodyContent
        {
            get
            {
                if (!string.IsNullOrEmpty(_bodyContent) || HttpRequest.HasFormContentType)
                {
                    return _bodyContent;
                }
                using (var readStream = new StreamReader(HttpRequest.Body, Encoding.UTF8))
                {
                    _bodyContent = readStream.ReadToEndAsync().Result; //readStream.ReadToEnd();
                }

                return _bodyContent;
            }
        }

        public IDictionary<string, string> Body()
        {
            var dict = new Dictionary<string, string>();
            if (string.IsNullOrEmpty(BodyContent))
            {
                return dict;
            }
            if (BodyContent.IsJson())
            {
                var obj = JsonConvert.DeserializeObject<object>(BodyContent);
                if (obj != null)
                {
                    var objdic = obj.ToDictionary();
                    foreach (var keyValuePair in objdic)
                    {
                        if (!dict.ContainsKey(keyValuePair.Key))
                        {
                            dict.Add(keyValuePair.Key, keyValuePair.Value.SerializeObjectToJson());
                        }
                    }
                }
                //return obj.ToDictionary();
            }
            else
            {
                //var dict = new Dictionary<string, string>();
                var pas = BodyContent.Split('&');
                foreach (var pa in pas)
                {
                    var pass = pa.Split('=');
                    if (pass.Length == 2)
                    {
                        dict[pass[0].Trim()] = pass[1].Trim();
                    }
                }
                //return dict;//.ToDynamic();
            }
            return dict;
        }
        public object Body(Type type)
        {
            if (string.IsNullOrEmpty(BodyContent))
            {
                return null;
            }

            var obj = JsonConvert.DeserializeObject(BodyContent, type);

            return obj;
        }

        //public IDictionary<string, string> DynamicBody()
        //{
        //    return Body<IDictionary<string, string>>();
        //}
        private IDictionary<string, string> DynamicHeader()
        {
            if (HttpRequest == null)
            {
                throw new ArgumentNullException();
            }

            var dict = new Dictionary<string, string>();
            foreach (var keyValuePair in HttpRequest.Headers)
            {
                if (!dict.ContainsKey(keyValuePair.Key))
                {
                    dict.Add(keyValuePair.Key, keyValuePair.Value);
                }
            }

            return dict;//.ToDynamic();
        }
        Dictionary<string, string> _CookiesData = null;
        private IDictionary<string, string> DynamicCookies()
        {
            if (HttpRequest == null)
            {
                throw new ArgumentNullException();
            }
            if (_CookiesData != null) return _CookiesData;

            _CookiesData = new Dictionary<string, string>();

            foreach (var keyValuePair in HttpRequest.Cookies)
            {
                if (!_CookiesData.ContainsKey(keyValuePair.Key))
                {
                    _CookiesData.Add(keyValuePair.Key, keyValuePair.Value);
                }
            }

            return _CookiesData;
        }
        Dictionary<string, string> _FormData = null;
        private IDictionary<string, string> DynamicFormData()
        {
            if (HttpRequest == null)
            {
                throw new ArgumentNullException();
            }
            if (_FormData != null) return _FormData;

            _FormData = new Dictionary<string, string>();
            if (HttpRequest.HasFormContentType)
            {
                try
                {
                    foreach (string k in HttpRequest.Form.Keys)
                    {
                        _FormData.Add(k, PathUtil.UrlDecode(HttpRequest.Form[k]));
                    }
                    foreach (IFormFile file in HttpRequest.Form.Files)
                    {
                        var fileName = file.Name;
                        if (string.IsNullOrWhiteSpace(fileName))
                        {
                            fileName = file.FileName;
                        }
                        _FormData.TryAdd(fileName, file.ToBase64());
                    }
                }
                catch { }
            }
            return _FormData;
        }
        Dictionary<string, string> _QueryData = null;
        private IDictionary<string, string> DynamicQuery()
        {
            if (HttpRequest == null)
            {
                throw new ArgumentNullException();
            }
            if (_QueryData != null) return _QueryData;

            _QueryData = new Dictionary<string, string>();
            foreach (var item in Params)
            {
                _QueryData[item.Key] = item.Value;
            }
            //if (_QueryData == null) _QueryData = new Dictionary<string, string>();
            foreach (var keyValuePair in HttpRequest.Query)
            {
                if (!_QueryData.ContainsKey(keyValuePair.Key))
                {
                    _QueryData.Add(keyValuePair.Key, PathUtil.UrlDecode(keyValuePair.Value));
                }
            }

            return _QueryData;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public IDictionary<string, string> InputBody()
        {
            if (HttpRequest.Method.ToUpper().Trim() == "GET")
            {
                return DynamicQuery();
            }
            else if (HttpRequest.HasFormContentType)
            {
                return DynamicFormData();
            }
            else
            {
                return Body();
            }
        }
    }
}
